home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Eudora 1.3.1 / source / unload.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  2.5 KB  |  84 lines  |  [TEXT/MPS ]

  1. #define FILE_NUM 51
  2. /************************************************************************
  3.  * ported from C++ code written by heksterb@cs.utwente.nl (Ben Hekster)
  4.  ************************************************************************/
  5. #pragma load EUDORA_LOAD
  6. #pragma parameter __D0 CurA5
  7. void *CurA5() = {0x200d};                    /* MOVE.L A5,D0 */
  8. #pragma parameter __D0 CurrentA7
  9. void *CurrentA7() = {0x200f};                    /* MOVE.L A7,D0 */
  10.  
  11. long UnloadUnneeded(long needed)
  12. {
  13.     long freed = 0;
  14.     short i;
  15.     void *mask = StripAddress((Ptr) 0xffffffff);
  16.     Handle codeH;
  17.     Size codeSize;
  18.  
  19.     /* find all purgeable but locked CODE resources in memory */
  20.     SetResLoad(false);
  21.     
  22.     for (i = 0; i < NUM_CODE; i++)
  23.     {
  24.         CodeAddress[i].start = nil;
  25.         codeH = GetResource('CODE', i);
  26.         if (codeH && *codeH)
  27.             /* is it a purgeable but locked resource? */
  28.             if ((HGetState(codeH) & 0xe0) == 0xe0)
  29.             {
  30.                 /* how big is it? */
  31.                 codeSize = GetHandleSize(codeH);
  32.                 if (codeSize > 0)
  33.                 {
  34.                     /* record the address range so it is eligible for purging */
  35.                     CodeAddress[i].start = (UPtr) ((long) *codeH & (long) mask);
  36.                     CodeAddress[i].end = CodeAddress[i].start + codeSize;
  37.                 }
  38.             }
  39.     }
  40.     SetResLoad(true);
  41.  
  42.     /* examine the stack */
  43.     {
  44.         Zone *applZone = ApplicZone();
  45.         void
  46.             *stackTop = CurrentA7(),                    /* stack to search */
  47.             *stackBase = *((void**) CurStackBase),
  48.             *heapStart = &applZone->heapData,    /* application zone data */
  49.             *heapEnd = applZone->bkLim;                /* and the end... */
  50.         char *a7;
  51.         void *stackData;
  52.         
  53.         /* search the stack for references to loaded segments */
  54.         for (a7 = (char*) stackTop; a7 < stackBase; a7 += 2)
  55.         {
  56.             /* is the address on the stack within the application heap? */
  57.             stackData = (void*) (*(long*) a7 & (long) mask);
  58.             if (stackData >= heapStart && stackData < heapEnd)
  59.                 /* is it in any of the code segments? */
  60.                 for (i = 0; i < NUM_CODE; i++)
  61.                     if (CodeAddress[i].start && stackData >= CodeAddress[i].start &&
  62.                             stackData < CodeAddress[i].end)
  63.                     {
  64.                         /* exclude it from unloading */
  65.                         CodeAddress[i].start = NULL;
  66.                         break;
  67.                     }
  68.             }
  69.         
  70.         /* unload everything that wasn't referenced inside the stack */
  71.         for (i = 2; i < NUM_CODE && needed>0; i++)
  72.             /* may we unload it? */
  73.             if (CodeAddress[i].start)
  74.             {
  75.                 /* ready to get it on! */
  76.                 UnloadSeg((char*) CurA5() +
  77.                     (*(short*) CurJTOffset) + (*(short*) CodeAddress[i].start) + 2);
  78.                 freed += CodeAddress[i].end-CodeAddress[i].start;
  79.                 needed -= CodeAddress[i].end-CodeAddress[i].start;
  80.             }
  81.     }
  82.     return(freed);
  83. }
  84.